/*
 * DatagramBuilder Library: serialize/deserialize data to/from datagram
 * Copyright (C) 2008 Rakov Ilya <RakovIlya@gmail.com>
 *
 * This library can be distributed under the terms of the GNU LGPLv2.
 * See the file COPYING.LIB.
 */


#ifndef DATAGRAM_PARSERIMPL_H_
#define DATAGRAM_PARSERIMPL_H_


/**
 * @file ParserImpl.h
 *
 * @brief Parser implementation file
 *
 * @date Dec 4, 2008
 * @author Rakov Ilya
 */


template < class T >
struct SerializeImpl;


class Parser::ScopedTransaction: public CRTPScopedTransaction< ScopedTransaction >
{

public:

  ScopedTransaction( Parser& parser )
  : parser_( parser )
  {
    parser_.transactNext_ = parser_.commitedNext_;
  }


  inline void Commit()
  {
    parser_.commitedNext_ = parser_.transactNext_;
  }


private:

  Parser& parser_;

};



Parser::Parser( const Container &container )
  : container_( container ),
    commitedNext_( 0 )
{
}


bool Parser::IsTreated() const
{
  return ( GetSize() == commitedNext_ );
}


size_t Parser::GetTreated() const
{
  return commitedNext_;
}


size_t Parser::GetSize() const
{
  return container_.GetSize();
}


template< class T >
void Parser::DeSerializeValue( T &value )
{
  transactNext_ += container_.DeSerializeValue( value, transactNext_ );
}


template< class SIZE_T, class T >
void Parser::DeSerializeValue( std::back_insert_iterator<T> inserter )
{
  transactNext_ += container_.DeSerializeValue< SIZE_T >( inserter, transactNext_ );
}


template< class T >
void Parser::DeSerializeValue( T &value, size_t offset ) const
{
  container_.DeSerializeValue( value, offset );
}


template< class CharType, class CharTrait >
void Parser::ToStream( std::basic_ostream< CharType, CharTrait > &out ) const
{
  container_.ToStream( out );
}


template < class T >
Parser& Parser::operator >>( const T &value )
{
  ScopedTransaction transaction( *this );

  SerializeImpl< const T >::DeSerialize( *this, value );

  return *this;
}


template < class T >
Parser& Parser::operator >>( T &value )
{
  ScopedTransaction transaction( *this );

  SerializeImpl< T >::DeSerialize( *this, value );

  return *this;
}


template < class T >
Parser& Parser::operator >>( Tag< T > value )
{
  ScopedTransaction transaction( *this );

  SerializeImpl< T >::DeSerializeTag( *this );
  SerializeImpl< T >::DeSerialize( *this, value.value_ );

  return *this;
}


template< class CharType, class CharTrait >
std::basic_ostream< CharType, CharTrait >&
operator <<( std::basic_ostream<CharType, CharTrait> &out, const Parser &obj )
{
  obj.ToStream( out );

  return out;
}



#endif /* DATAGRAM_PARSERIMPL_H_ */
